home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / fljpeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  11.6 KB  |  393 lines

  1. /*****************************************************************
  2.  * fljpeg.c: FBM Release 1.2 24-Mar-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1993 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * This code is based on example.c from the JPEG library.
  11.  *
  12.  * fljpeg.c: 
  13.  *
  14.  * CONTENTS
  15.  *    read_jpeg (image, rfile, mstr, mlen)
  16.  *    write_jpeg (image, wfile)
  17.  *
  18.  * EDITLOG
  19.  *    LastEditDate = Mon Jun 25 00:18:04 1990 - Michael Mauldin
  20.  *    LastFileName = /usr2/mlm/src/misc/fbm/fljpeg.c
  21.  *
  22.  * HISTORY
  23.  * 31-Mar-93  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  24.  *    Created.
  25.  *****************************************************************/
  26.  
  27. # include <stdio.h>
  28. # include <math.h>
  29. # include "fbm.h"
  30.  
  31. # define RED 0
  32. # define GRN 1
  33. # define BLU 2
  34.  
  35. static FBM *fbm_image; /* Global to allow allow access to methods */
  36. static int row;
  37.  
  38. #ifndef lint
  39. static char *fbmid =
  40. "$FBM fljpeg.c <1.2> 24-Mar-93  (C) 1993 by Michael Mauldin, source \
  41. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  42. #endif
  43.  
  44. # ifdef DO_JPEG
  45. # include <setjmp.h>
  46. # include <sys/types.h>
  47. # include "jinclude.h"
  48.  
  49.  
  50. /*================ Compressor ================*/
  51.  
  52. void input_init (cinfo)
  53. compress_info_ptr cinfo;
  54. {
  55.   /* The fields are initialized in write_jpeg */
  56. }
  57.  
  58.  
  59. /*
  60.  * This function is called repeatedly and must supply the next row of pixels
  61.  * on each call.  The rows MUST be returned in top-to-bottom order if you want
  62.  * your JPEG files to be compatible with everyone else's. 
  63.  */
  64.  
  65. void get_input_row (cinfo, pixel_row)
  66. compress_info_ptr cinfo;
  67. JSAMPARRAY pixel_row;
  68. /* Read next row of pixels into pixel_row[][] */
  69. {
  70.   /* This example shows how you might read RGB data (3 components)
  71.    * from an input file in which the data is stored 3 bytes per pixel
  72.    * in left-to-right, top-to-bottom order.
  73.    */
  74.   register FILE * infile = cinfo->input_file;
  75.   register JSAMPROW obm;
  76.   register unsigned char *ibm;
  77.   register int k;
  78.   register long col;
  79.  
  80.   if (row >= fbm_image->hdr.rows) return;
  81.  
  82.   /* Copy a row from each plane into the appropriate pixel_row */
  83.   for (k=0; k<cinfo->input_components; k++)
  84.   { obm = pixel_row[k];
  85.     ibm = &fbm_image->bm[k * fbm_image->hdr.plnlen + 
  86.              row * fbm_image->hdr.rowlen];
  87.  
  88.     for (col = 0; col < cinfo->image_width; col++)
  89.     { *obm++ = (JSAMPLE) *ibm++; }
  90.   }
  91.   
  92.   row++;
  93. }
  94.  
  95. void input_term (cinfo)
  96. compress_info_ptr cinfo;
  97. /* Finish up at the end of the input */
  98. {
  99.   /* no work to do */
  100. }
  101.  
  102. /*
  103.  * This routine must determine what output JPEG file format is to be written,
  104.  */
  105.  
  106. void c_ui_method_selection (cinfo)
  107. compress_info_ptr cinfo;
  108. {
  109.   /* If the input is gray scale, generate a monochrome JPEG file. */
  110.   if (cinfo->in_color_space == CS_GRAYSCALE)
  111.     j_monochrome_default(cinfo);
  112.  
  113.   /* For now, always select JFIF output format. */
  114.   jselwjfif(cinfo);
  115. }
  116.  
  117. /****************************************************************
  118.  * write_jpeg: Set up methods and call compressor
  119.  ****************************************************************/
  120.  
  121. write_jpeg (image, wfile, quality)
  122. FBM *image;
  123. FILE *wfile;
  124. int quality;
  125. {
  126.   struct Compress_info_struct cinfo;
  127.   struct Compress_methods_struct c_methods;
  128.   struct External_methods_struct e_methods;
  129.  
  130.   /* Global for get_input_row */
  131.   fbm_image = image;
  132.  
  133.   /* Initialize the system-dependent method pointers. */
  134.   cinfo.methods = &c_methods;    /* links to method structs */
  135.   cinfo.emethods = &e_methods;
  136.   jselerror(&e_methods);    /* select std error/trace message routines */
  137.   jselmemmgr(&e_methods);    /* select std memory allocation routines */
  138.  
  139.   /*-------- Code that normally goes in input_init --------*/
  140.   cinfo.image_width = image->hdr.cols;        /* width in pixels */
  141.   cinfo.image_height = image->hdr.rows;    /* height in pixels */
  142.   cinfo.input_components = image->hdr.planes;    /* or 1 for grayscale */
  143.  
  144.   if (cinfo.input_components == 1)
  145.   { cinfo.in_color_space = CS_GRAYSCALE; }
  146.   else
  147.   { cinfo.in_color_space = CS_RGB; }
  148.  
  149.   cinfo.data_precision = image->hdr.physbits;    /* bits/pixel comp. value */
  150.   
  151.   row = 0;
  152.   /*---------------------------------------------------*/
  153.  
  154.   /* Here, set up pointers to your own routines for input data handling
  155.    * and post-init parameter selection.
  156.    */
  157.   c_methods.input_init = input_init;        /* now a nop */
  158.   c_methods.get_input_row = get_input_row;
  159.   c_methods.input_term = input_term;
  160.   c_methods.c_ui_method_selection = c_ui_method_selection;
  161.  
  162.   /* Set up default JPEG parameters in the cinfo data structure. */
  163.   j_c_defaults(&cinfo, quality, TRUE);
  164.  
  165.   cinfo.input_file = NULL;    /* if no actual input file involved */
  166.   cinfo.output_file = wfile;
  167.  
  168.   /* Here we go! */
  169.   jpeg_compress(&cinfo);
  170. }
  171.  
  172. /* ================ Decompressor ================*/
  173.  
  174. /* These static variables are needed by the error routines. */
  175. static jmp_buf setjmp_buffer;        /* for return to caller */
  176. static external_methods_ptr emethods;    /* for access to message_parm */
  177.  
  178. /* This routine is used for any and all trace, debug, or error printouts
  179.  * from the JPEG code.  The parameter is a printf format string; up to 8
  180.  * integer data values for the format string have been stored in the
  181.  * message_parm[] field of the external_methods struct.
  182.  */
  183.  
  184. void trace_message (msgtext)
  185. char *msgtext;
  186. {
  187.   fprintf(stderr, msgtext,
  188.       emethods->message_parm[0], emethods->message_parm[1],
  189.       emethods->message_parm[2], emethods->message_parm[3],
  190.       emethods->message_parm[4], emethods->message_parm[5],
  191.       emethods->message_parm[6], emethods->message_parm[7]);
  192.   fprintf(stderr, "\n");    /* there is no \n in the format string! */
  193. }
  194.  
  195. /*
  196.  * The error_exit() routine should not return to its caller.  The default
  197.  * routine calls exit(), but here we assume that we want to return to
  198.  * read_JPEG_file, which has set up a setjmp context for the purpose.
  199.  * You should make sure that the free_all method is called, either within
  200.  * error_exit or after the return to the outer-level routine.
  201.  */
  202.  
  203. void error_exit (msgtext)
  204. char *msgtext;
  205. {
  206.   trace_message(msgtext);    /* report the error message */
  207.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  208.   longjmp(setjmp_buffer, 1);    /* return control to outer routine */
  209. }
  210.  
  211. /****************************************************************
  212.  * output_init;
  213.  ****************************************************************/
  214.  
  215.  
  216. void output_init (cinfo)
  217. decompress_info_ptr cinfo;
  218. { int rowlen;
  219.  
  220.   /* Set image size */
  221.   fbm_image->hdr.rows = cinfo->image_height;
  222.   fbm_image->hdr.cols = cinfo->image_width;
  223.   fbm_image->hdr.bits = cinfo->data_precision;
  224.   fbm_image->hdr.physbits = 8;
  225.   fbm_image->hdr.planes = (cinfo->out_color_space == CS_GRAYSCALE) ? 1 : 3;
  226.  
  227.   /*
  228.    * Check for too many bits of precision.  In the future, we
  229.    * should just truncate to the 8 highest bits in this case.
  230.    */
  231.  
  232.   if (cinfo->data_precision > 8)
  233.   { char mbuf[256];
  234.     sprintf (mbuf, "error:input has %d bits precision, can only handle 8\n",
  235.          cinfo->data_precision);
  236.     error_exit (mbuf);
  237.   }
  238.  
  239.   /* Make sure rowlen is extended to an even number of bytes */
  240.   if ((rowlen = fbm_image->hdr.cols) & 1) rowlen++;
  241.   fbm_image->hdr.rowlen = rowlen;
  242.   fbm_image->hdr.plnlen = rowlen * fbm_image->hdr.rows;
  243.  
  244.   /* ALways unmapped output */
  245.   fbm_image->hdr.clrlen = 0;
  246.  
  247.   /* Miscellaneous annotations */
  248.   fbm_image->hdr.aspect = 1.0;
  249.   fbm_image->hdr.title[0] = '\0';
  250.   strcpy (fbm_image->hdr.credits, "via JPEG");
  251.   
  252.   alloc_fbm (fbm_image);
  253.  
  254.   row = 0;  /* Global variable used in put_pixel_rows */
  255. }
  256.  
  257. /*
  258.  * This routine is called if and only if you have set cinfo->quantize_colors
  259.  * to TRUE.  We don't need this for FBM.
  260.  */
  261.  
  262. void put_color_map ()
  263. {
  264.   fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
  265. }
  266.  
  267. /*****************************************************************
  268.  * put_pixel_rows:  Called with 1 or more rows in top to bottom order 
  269.  *****************************************************************/
  270.  
  271. void put_pixel_rows (cinfo, num_rows, pixel_data)
  272. decompress_info_ptr cinfo;
  273. int num_rows;
  274. JSAMPIMAGE pixel_data;
  275. { register FILE * outfile = cinfo->output_file;
  276.   register JSAMPROW ibm;
  277.   register unsigned char *obm;
  278.   register int i, j, k;
  279.  
  280.   for (j = 0; j < num_rows && row < fbm_image->hdr.rows; j++, row++)
  281.   { for (k=0; k < fbm_image->hdr.planes; k++)
  282.     { ibm = pixel_data[k][j];
  283.       obm = &fbm_image->bm[k * fbm_image->hdr.plnlen + 
  284.                row * fbm_image->hdr.rowlen];
  285.       
  286.       for (i = cinfo->image_width; i > 0; i--, ibm++)
  287.       { *obm++ = GETJSAMPLE (*ibm); }
  288.     }
  289.   }
  290. }
  291.  
  292. void output_term ()
  293. {
  294.   /* no work to do */
  295. }
  296.  
  297. /*****************************************************************
  298.  * Now we have overall control and parameter selection routines.
  299.  *****************************************************************/
  300.  
  301. void
  302. d_ui_method_selection (cinfo)
  303. decompress_info_ptr cinfo;
  304. {
  305.   /* if grayscale input, force grayscale output; */
  306.   /* else leave the output colorspace as set by main routine. */
  307.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  308.     cinfo->out_color_space = CS_GRAYSCALE;
  309.  
  310.   /* select output routines */
  311.   cinfo->methods->output_init = output_init;
  312.   cinfo->methods->put_color_map = put_color_map;
  313.   cinfo->methods->put_pixel_rows = put_pixel_rows;
  314.   cinfo->methods->output_term = output_term;
  315. }
  316.  
  317. /*****************************************************************
  318.  * OK, here is the main function that actually causes everything to happen.
  319.  * We assume here that all decompression parameters can be default values.
  320.  * The routine returns 1 if successful, 0 if not.
  321.  *****************************************************************/
  322.  
  323. read_jpeg (image, rfile)
  324. FBM *image;
  325. FILE *rfile;
  326.   struct Decompress_info_struct cinfo;
  327.   struct Decompress_methods_struct dc_methods;
  328.   struct External_methods_struct e_methods;
  329.  
  330.   fbm_image = image;
  331.  
  332.   /* Set input file from caller and specify no output files */
  333.   cinfo.input_file = rfile;
  334.   cinfo.output_file = NULL;    /* if no actual output file involved */
  335.  
  336.   /* Initialize the system-dependent method pointers. */
  337.   cinfo.methods = &dc_methods;    /* links to method structs */
  338.   cinfo.emethods = &e_methods;
  339.  
  340.   /* Here we supply our own error handler; compare to use of standard error
  341.    * handler in the previous write_JPEG_file example.
  342.    */
  343.   emethods = &e_methods;    /* save struct addr for possible access */
  344.   e_methods.error_exit = error_exit; /* supply error-exit routine */
  345.   e_methods.trace_message = trace_message; /* supply trace-message routine */
  346.   e_methods.trace_level = 0;    /* default = no tracing */
  347.   e_methods.num_warnings = 0;    /* no warnings emitted yet */
  348.   e_methods.first_warning_level = 0; /* display first corrupt-data warning */
  349.   e_methods.more_warning_level = 3; /* but suppress additional ones */
  350.  
  351.   /* prepare setjmp context for possible exit from error_exit */
  352.   if (setjmp(setjmp_buffer))
  353.   { fclose(cinfo.input_file);
  354.     return (0);
  355.   }
  356.  
  357.   jselmemmgr(&e_methods);
  358.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  359.   j_d_defaults(&cinfo, TRUE);
  360.   jselrjfif(&cinfo);
  361.  
  362.   /* Here we go! */
  363.   jpeg_decompress(&cinfo);
  364.  
  365.   fclose(cinfo.input_file);
  366.  
  367.   return (1);
  368. }
  369. # else
  370.  
  371. /****************************************************************
  372.  * stubs for reading and writing JPEG, since the library isn't loaded
  373.  ****************************************************************/
  374.  
  375. write_jpeg (image, wfile, quality)
  376. FBM *image;
  377. FILE *wfile;
  378. int quality;
  379. {
  380.   fprintf (stderr, "JPEG support was not compiled into this executable\n");
  381.   exit (1);
  382. }
  383.  
  384. read_jpeg (image, rfile)
  385. FBM *image;
  386. FILE *rfile;
  387.   fprintf (stderr, "JPEG support was not compiled into this executable\n");
  388.   exit (1);
  389. }
  390. # endif
  391.